package com.ada.reflection;

import com.google.gson.internal.$Gson$Types;

import java.lang.reflect.*;

public class App {

    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {
        Method[] ms = User.class.getMethods();
        for (Method m : ms) {
            System.out.println(m.getName());
            if ("showMessage".equalsIgnoreCase(m.getName())) {
                // m.invoke(new User());
            }
        }


        Method method = ChildExample.class.getMethod("getList");
        Type returnType = method.getGenericReturnType();

        if (returnType instanceof ParameterizedType) {
            ParameterizedType type = (ParameterizedType) returnType;
            Type[] typeArguments = type.getActualTypeArguments();
            System.out.println(typeArguments[0]);  // 输出 "class java.lang.String"


            Type actualTypeArgument = typeArguments[0];




            if (actualTypeArgument instanceof Class) {
                System.out.println(actualTypeArgument + "  actualTypeArgument");
            }

            if (actualTypeArgument instanceof WildcardType) {
                WildcardType wildcardType = (WildcardType) actualTypeArgument;

                // assert wildcardType.getUpperBounds().length == 1;
                Type upperBoundType = wildcardType.getUpperBounds()[0];

                // assert upperBoundType instanceof Class;
                if (Object.class.equals(upperBoundType)) {
                    if (wildcardType.getLowerBounds().length == 0) {
                        // Collection<?>
                    } else {
                    }
                }

                // throw new JSONException("not support type : " +
                // collectionType);return parse();
            }

            if (actualTypeArgument instanceof TypeVariable) {
                TypeVariable<?> typeVariable = (TypeVariable<?>) actualTypeArgument;
                Type[] bounds = typeVariable.getBounds();


                Type boundType = bounds[0];
                Class<?> rawType = $Gson$Types.getRawType(boundType);
                System.out.println(rawType);
                if (boundType instanceof Class) {
                    System.out.println(boundType + "  boundType");
                  User user=  createInstance(boundType);
                  user.showMessage();
                }
            }

            if (actualTypeArgument instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) actualTypeArgument;

                System.out.println(parameterizedType + "  parameterizedType");

            }

        }
    }
    private  static  <V> V createInstance(Type type) {
        try {
            Class<V> clazz = (Class<V>) (type instanceof Class ? type : ((ParameterizedType) type).getRawType());
            return clazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
